export default {
    name: 'BForm',
    props: {
        config: {
            type: Array,
            default() {
                return []
            }
        },
        form: {
            type: Object,
            default() {
                return {}
            }
        },
        rule: {
            type: Object,
            default() {
                return {}
            }
        }
    },
    methods: {
        async validate(cb, isShowNotice = true) {
            this.$refs.formRules.validate(valid => {
                cb(valid)
                if ((!valid) && isShowNotice) {
                    this.$noticeWarning('请填写完整')
                }
            })
        },
        async resetFields() {
            this.$refs.formRules.resetFields()
        },
        async clearValidate() {
            this.$refs.formRules.clearValidate()
        },
        getProjectInfo(val) {
            this.$emit("getProjectInfo", val)
        },
        selectOrg(val, key) {
            if(val.length) {
                if (key.indexOf('branch') > -1) {
                    this.$set(this.form, key, val[val.length - 1].orgId)
                } else {
                    this.$set(this.form, key, val[val.length - 2].projectId)
                }
                this.$emit("selectOrg", val)
                this.$refs.formRules.clearValidate(key)
            }
        }
    },
    render(h, context) {
        //Form.Item 会对唯一子元素进行劫持，并监听 blur 和 change 事件，来达到自动校验的目的，所以请确保表单域没有其它元素包裹。
        // 如果有多个子元素，将只会监听第一个子元素的变化。
        // 如果要监听的表单域不满足自动监听的条件，可以通过如下方式手动检测：
        let manualCheckProp = (item) => {
            this.$watch('form.' + item.value, () => {
                this.$refs[item.value].onFieldChange()
            })
            return item.render()
        }

        //递归获取值，针对'a.b.c.d.e'这种深层调用，递归检测有无对应值，没有就设置为{}，并进行下一级。直到最后一级时，设置为undefined，并返回''
        //设置最终值为undefined，是因为andt的select组件必须值为undefined的时候才能正常显示placeholder
        let getDeepValue = (path, obj, index = 0,defaultValue=undefined) => {
            let key = path[index]
            if (key in obj) {
                if (path.length - 1 === index) {
                  return obj[key]
                } else {
                    return getDeepValue(path, obj[key], index + 1,defaultValue)
                }
            } else {
                if (path.length - 1 === index) {
                    // obj[key] = ''
                    // this.$set(obj, key, '')
                    this.$set(obj, key, defaultValue)
                    return defaultValue
                } else {
                    // obj[key] = {}
                    this.$set(obj, key, {})
                    return getDeepValue(path, obj[key], index + 1,defaultValue)
                }
            }
        }
        //递归设置值，这里不用this.$set为设置了，直接=就可以了
        let setDeepValue = (path, obj, value, index = 0,defaultValue=undefined) => {
            let key = path[index]
            if (key in obj) {
                if (path.length - 1 === index) {
                    obj[key] = value
                } else {
                    setDeepValue(path, obj[key], value, index + 1,defaultValue)
                }
            } else {
                if (path.length - 1 === index) {
                    obj[key] = defaultValue
                } else {
                    obj[key] = {}
                    setDeepValue(path, obj[key], value, index + 1,defaultValue)
                }
            }
        }

        return (
          <a-form-model props={{ model: this.form }} ref="formRules" rules={this.rule}>
              {this.config.map(rowItem => {
                  return (
                    <a-row>
                        {rowItem.children.map(item => {
                            let component
                            if (typeof item.type === 'object') {
                                component = item.type
                            }
                            return (
                              (('show' in item) ? item.show : true) && (
                                <a-col v-show={!item.hidden}  span={item.span ||item.colSpan || 8} style={item.noFixed ? '' : 'height:65px;'}>
                                    {item.type === 'orgTree' ?   <a-form-model-item colon={item.colon} label={item.label} prop={item.keyName}
                                      >
                                        {
                                            !item.isNoBorder ? (
                                              <org-tree-select
                                                disabled={item.disabled}
                                                value={this.form[item.keyName]}
                                                check-strictly={item.checkStrictly}
                                                isNeedAuth={item.isNeedAuth}
                                                isAutoSelectFirst={item.isAutoSelectFirst}
                                                notIsAutoSelectFirst ={item.notIsAutoSelectFirst}
                                                orgQuery={item.orgQuery}
                                                isShowProject={item.isShowProject}
                                                isQueryProjecDetail={item.isQueryProjecDetail}
                                                statusSet={item.statusSet}
                                                onGetProjectInfo={this.getProjectInfo}
                                                onSelect={(val)=>{this.selectOrg(val, item.keyName)}}/>
                                            ) : <span className="text_name">{this.form[item.viewName]}</span>
                                        }
                                    </a-form-model-item> :
                                      <a-form-model-item label={item.label}
                                                         className={item.forceRemoveValid ? 'forceRemoveValid' : ''}
                                                         ref={item.value}
                                                         autoLink={item.type !== 'custom'}
                                                         prop={('prop' in item) ? item.prop : item.value}
                                                         rules={('rules' in item) ? item.rules : null}
                                      >
                                          {typeof item.type === 'object' && (
                                            <component
                                              form={this.form}
                                              placeholder={item.attrs?.disabled ? '' : (item.placeholder || '请选择')}
                                              props={{ ...item.attrs }}
                                              attrs={{ ...item.attrs }}
                                              on={{ ...item.on }}
                                              onchange={e => setDeepValue(item.value.split('.'), this.form, e)}
                                              value={getDeepValue(item.value.split('.'), this.form)}
                                              // v-model={this.form[item.value]}
                                            />
                                          )}
                                          {item.type === 'text' && (
                                            <span>{getDeepValue(item.value.split('.'), this.form)}</span>
                                          )}
                                          {item.type === 'button' && (
                                            <a-button
                                              on={{ ...item.on }}
                                              props={{ ...item.attrs }}
                                              attrs={{ ...item.attrs }}
                                            >
                                                {item.attrs.text}
                                            </a-button>
                                          )}
                                          {item.type === 'date-picker' && (
                                            <a-date-picker
                                              placeholder={item.attrs?.disabled ? '' : (item.placeholder || '请选择')}
                                              valueFormat="x"
                                              props={{ ...item.attrs }}
                                              attrs={{ ...item.attrs }}
                                              on={{ ...item.on }}
                                              onchange={e => setDeepValue(item.value.split('.'), this.form, e)}
                                              value={getDeepValue(item.value.split('.'), this.form)}
                                            />
                                          )}
                                          {item.type === 'month-picker' && (
                                            <a-month-picker
                                              placeholder={item.attrs?.disabled ? '' : (item.placeholder || '请选择')}
                                              valueFormat="x"
                                              props={{ ...item.attrs }}
                                              attrs={{ ...item.attrs }}
                                              on={{ ...item.on }}
                                              onchange={e => setDeepValue(item.value.split('.'), this.form, e)}
                                              value={getDeepValue(item.value.split('.'), this.form)}
                                            />
                                          )}
                                          {item.type === 'range-picker' && (
                                            <a-range-picker
                                              valueFormat="x"
                                              props={{ ...item.attrs }}
                                              attrs={{ ...item.attrs }}
                                              on={{ ...item.on }}
                                              onchange={e => setDeepValue(item.value.split('.'), this.form, e)}
                                              value={getDeepValue(item.value.split('.'), this.form)}
                                            />
                                          )}
                                          {item.type === 'input' && (
                                            <b-input
                                              placeholder={item.attrs?.disabled ? '' : (item.placeholder || '请输入')}
                                              props={{ ...item.attrs }}
                                              attrs={{ ...item.attrs }}
                                              on={{ ...item.on }}
                                              onchange={e => setDeepValue(item.value.split('.'), this.form, e.target.value)}
                                              value={getDeepValue(item.value.split('.'), this.form)}
                                            />
                                          )}
                                          {item.type === 'number' && (
                                            <b-input-number
                                              placeholder={item.attrs?.disabled ? '' : (item.placeholder || '请输入')}
                                              props={{ ...item.attrs }}
                                              attrs={{ ...item.attrs }}
                                              on={{ ...item.on }}
                                              onpackageInput={e => setDeepValue(item.value.split('.'), this.form, e)}
                                              value={getDeepValue(item.value.split('.'), this.form)}
                                            />
                                          )}
                                          {item.type === 'input-search' && (
                                            <a-input-search
                                              placeholder={item.attrs?.disabled ? '' : (item.placeholder || '请选择')}
                                              props={{ ...item.attrs }}
                                              attrs={{ ...item.attrs }}
                                              on={{ ...item.on }}
                                              onchange={e => setDeepValue(item.value.split('.'), this.form, e.target.value)}
                                              value={getDeepValue(item.value.split('.'), this.form)}
                                            />
                                          )}
                                          {item.type === 'textarea' && (
                                            <b-textarea
                                              placeholder={item.attrs?.disabled ? '' : (item.placeholder || '请输入')}
                                              props={{ ...item.attrs }}
                                              attrs={{ ...item.attrs }}
                                              on={{ ...item.on }}
                                              onchange={e => setDeepValue(item.value.split('.'), this.form, e.target.value)}
                                              value={getDeepValue(item.value.split('.'), this.form)}
                                            />
                                          )}
                                          {item.type === 'radio' && (
                                            <a-radio-group
                                              placeholder={item.attrs?.disabled ? '' : (item.placeholder || '请输入')}
                                              props={{ ...item.attrs }}
                                              attrs={{ ...item.attrs }}
                                              on={{ ...item.on }}
                                              onchange={e => setDeepValue(item.value.split('.'), this.form, e.target.value)}
                                              value={getDeepValue(item.value.split('.'), this.form)}
                                            >
                                                {item.attrs.data.map(v => {
                                                    let option = { label: v.name, value: v.id }
                                                    if (item.attrs.key) {
                                                        option.label = v[item.attrs.key[0]]
                                                        option.value = v[item.attrs.key[1]]
                                                    }
                                                    return (
                                                      <a-radio style={item.attrs.horizontal ? {} : {
                                                          display: 'block',
                                                          height: '30px',
                                                          lineHeight: '30px'
                                                      }}
                                                               disabled={v.disabled}
                                                               value={option.value}
                                                      >
                                                          {option.label}
                                                      </a-radio>
                                                    )
                                                })}
                                            </a-radio-group>
                                          )}
                                          {item.type === 'select' && (
                                            <a-select
                                              placeholder={item.attrs?.disabled ? '' : (item.placeholder || '请选择')}
                                              props={{ ...item.attrs }}
                                              attrs={{ ...item.attrs }}
                                              on={{ ...item.on }}
                                              v-model={this.form[item.value]}
                                            >
                                                {item.attrs.data.map(v => {
                                                    let option = { label: v.name, value: v.id }
                                                    if (item.attrs.key) {
                                                        option.label = v[item.attrs.key[0]]
                                                        option.value = v[item.attrs.key[1]]
                                                    }
                                                    return (
                                                      <a-select-option value={option.value}>
                                                          {option.label}
                                                      </a-select-option>
                                                    )
                                                })}
                                            </a-select>
                                          )}
                                          {item.type === 'custom' && manualCheckProp(item)}
                                      </a-form-model-item>}

                                </a-col>
                              )
                            )
                        })}
                    </a-row>
                  )
              })}
          </a-form-model>
        )
    }
}
